﻿////------------------------------------------------------------
//// Game Framework
//// Copyright © 2013-2021 Jiang Yin. All rights reserved.
//// Homepage: https://gameframework.cn/
//// Feedback: mailto:ellan@gameframework.cn
////------------------------------------------------------------

//using GameFramework;
//using GameFramework.FileSystem;
//using GameFramework.Resource;
//using System;
//using System.Collections.Generic;
//using System.IO;
//using System.Linq;
//using System.Xml;
//using UnityEditor;
//using UnityEngine;
//using UnityGameFramework.Runtime;

//namespace UnityGameFramework.Editor.ResourceTools
//{
//    public sealed partial class ResourceBuilderController
//    {
//        private const string RemoteVersionListFileName = "GameFrameworkVersion.dat";
//        private const string LocalVersionListFileName = "GameFrameworkList.dat";
//        private const string DefaultExtension = "dat";
//        private const string NoneOptionName = "<None>";
//        private static readonly int AssetsStringLength = "Assets".Length;

//        private readonly string m_ConfigurationPath;
//        private readonly ResourceCollection m_ResourceCollection;
//        private readonly ResourceAnalyzerController m_ResourceAnalyzerController;
//        private readonly SortedDictionary<string, ResourceData> m_ResourceDatas;
//        private readonly Dictionary<string, IFileSystem> m_OutputPackageFileSystems;
//        private readonly Dictionary<string, IFileSystem> m_OutputPackedFileSystems;
//        private readonly BuildReport m_BuildReport;
//        private readonly List<string> m_CompressionHelperTypeNames;
//        private readonly List<string> m_BuildEventHandlerTypeNames;
//        private IBuildEventHandler m_BuildEventHandler;
//        private IFileSystemManager m_FileSystemManager;

//        public ResourceBuilderController()
//        {
//            m_ConfigurationPath = Type.GetConfigurationPath<ResourceBuilderConfigPathAttribute>() ?? Utility.Path.GetRegularPath(Path.Combine(Application.dataPath, "GameFramework/Configs/ResourceBuilder.xml"));

//            m_ResourceCollection = new ResourceCollection();
//            m_ResourceCollection.OnLoadingResource += delegate (int index, int count)
//            {
//                if (OnLoadingResource != null)
//                {
//                    OnLoadingResource(index, count);
//                }
//            };

//            m_ResourceCollection.OnLoadingAsset += delegate (int index, int count)
//            {
//                if (OnLoadingAsset != null)
//                {
//                    OnLoadingAsset(index, count);
//                }
//            };

//            m_ResourceCollection.OnLoadCompleted += delegate ()
//            {
//                if (OnLoadCompleted != null)
//                {
//                    OnLoadCompleted();
//                }
//            };

//            m_ResourceAnalyzerController = new ResourceAnalyzerController(m_ResourceCollection);

//            m_ResourceAnalyzerController.OnAnalyzingAsset += delegate (int index, int count)
//            {
//                if (OnAnalyzingAsset != null)
//                {
//                    OnAnalyzingAsset(index, count);
//                }
//            };

//            m_ResourceAnalyzerController.OnAnalyzeCompleted += delegate ()
//            {
//                if (OnAnalyzeCompleted != null)
//                {
//                    OnAnalyzeCompleted();
//                }
//            };

//            m_ResourceDatas = new SortedDictionary<string, ResourceData>(StringComparer.Ordinal);
//            m_OutputPackageFileSystems = new Dictionary<string, IFileSystem>(StringComparer.Ordinal);
//            m_OutputPackedFileSystems = new Dictionary<string, IFileSystem>(StringComparer.Ordinal);
//            m_BuildReport = new BuildReport();

//            m_CompressionHelperTypeNames = new List<string>
//            {
//                NoneOptionName
//            };

//            m_BuildEventHandlerTypeNames = new List<string>
//            {
//                NoneOptionName
//            };

//            m_CompressionHelperTypeNames.AddRange(Type.GetRuntimeOrEditorTypeNames(typeof(Utility.Compression.ICompressionHelper)));
//            m_BuildEventHandlerTypeNames.AddRange(Type.GetRuntimeOrEditorTypeNames(typeof(IBuildEventHandler)));
//            m_BuildEventHandler = null;
//            m_FileSystemManager = null;

//            Platforms = Platform.Undefined;
//            AssetBundleCompression = AssetBundleCompressionType.LZ4;
//            CompressionHelperTypeName = string.Empty;
//            AdditionalCompressionSelected = false;
//            ForceRebuildAssetBundleSelected = false;
//            BuildEventHandlerTypeName = string.Empty;
//            OutputDirectory = string.Empty;
//            OutputPackageSelected = OutputFullSelected = OutputPackedSelected = true;
//        }

//        public string ProductName
//        {
//            get
//            {
//                return PlayerSettings.productName;
//            }
//        }

//        public string CompanyName
//        {
//            get
//            {
//                return PlayerSettings.companyName;
//            }
//        }

//        public string GameIdentifier
//        {
//            get
//            {
//#if UNITY_5_6_OR_NEWER
//                return PlayerSettings.applicationIdentifier;
//#else
//                return PlayerSettings.bundleIdentifier;
//#endif
//            }
//        }

//        public string GameFrameworkVersion
//        {
//            get
//            {
//                return GameFramework.Version.GameFrameworkVersion;
//            }
//        }

//        public string UnityVersion
//        {
//            get
//            {
//                return Application.unityVersion;
//            }
//        }

//        public string ApplicableGameVersion
//        {
//            get
//            {
//                return Application.version;
//            }
//        }

//        public int InternalResourceVersion
//        {
//            get;
//            set;
//        }

//        public Platform Platforms
//        {
//            get;
//            set;
//        }

//        public AssetBundleCompressionType AssetBundleCompression
//        {
//            get;
//            set;
//        }

//        public string CompressionHelperTypeName
//        {
//            get;
//            set;
//        }

//        public bool AdditionalCompressionSelected
//        {
//            get;
//            set;
//        }

//        public bool ForceRebuildAssetBundleSelected
//        {
//            get;
//            set;
//        }

//        public string BuildEventHandlerTypeName
//        {
//            get;
//            set;
//        }

//        public string OutputDirectory
//        {
//            get;
//            set;
//        }

//        public bool OutputPackageSelected
//        {
//            get;
//            set;
//        }

//        public bool OutputFullSelected
//        {
//            get;
//            set;
//        }

//        public bool OutputPackedSelected
//        {
//            get;
//            set;
//        }

//        public bool IsValidOutputDirectory
//        {
//            get
//            {
//                if (string.IsNullOrEmpty(OutputDirectory))
//                {
//                    return false;
//                }

//                if (!Directory.Exists(OutputDirectory))
//                {
//                    return false;
//                }

//                return true;
//            }
//        }

//        public string WorkingPath
//        {
//            get
//            {
//                if (!IsValidOutputDirectory)
//                {
//                    return string.Empty;
//                }

//                return Utility.Path.GetRegularPath(new DirectoryInfo(Utility.Text.Format("{0}/Working/", OutputDirectory)).FullName);
//            }
//        }

//        public string OutputPackagePath
//        {
//            get
//            {
//                if (!IsValidOutputDirectory)
//                {
//                    return string.Empty;
//                }

//                return Utility.Path.GetRegularPath(new DirectoryInfo(Utility.Text.Format("{0}/Package/{1}_{2}/", OutputDirectory, ApplicableGameVersion.Replace('.', '_'), InternalResourceVersion)).FullName);
//            }
//        }

//        public string OutputFullPath
//        {
//            get
//            {
//                if (!IsValidOutputDirectory)
//                {
//                    return string.Empty;
//                }

//                return Utility.Path.GetRegularPath(new DirectoryInfo(Utility.Text.Format("{0}/Full/{1}_{2}/", OutputDirectory, ApplicableGameVersion.Replace('.', '_'), InternalResourceVersion)).FullName);
//            }
//        }

//        public string OutputPackedPath
//        {
//            get
//            {
//                if (!IsValidOutputDirectory)
//                {
//                    return string.Empty;
//                }

//                return Utility.Path.GetRegularPath(new DirectoryInfo(Utility.Text.Format("{0}/Packed/{1}_{2}/", OutputDirectory, ApplicableGameVersion.Replace('.', '_'), InternalResourceVersion)).FullName);
//            }
//        }

//        public string BuildReportPath
//        {
//            get
//            {
//                if (!IsValidOutputDirectory)
//                {
//                    return string.Empty;
//                }

//                return Utility.Path.GetRegularPath(new DirectoryInfo(Utility.Text.Format("{0}/BuildReport/{1}_{2}/", OutputDirectory, ApplicableGameVersion.Replace('.', '_'), InternalResourceVersion)).FullName);
//            }
//        }

//        public event GameFrameworkAction<int, int> OnLoadingResource = null;

//        public event GameFrameworkAction<int, int> OnLoadingAsset = null;

//        public event GameFrameworkAction OnLoadCompleted = null;

//        public event GameFrameworkAction<int, int> OnAnalyzingAsset = null;

//        public event GameFrameworkAction OnAnalyzeCompleted = null;

//        public event GameFrameworkFunc<string, float, bool> ProcessingAssetBundle = null;

//        public event GameFrameworkFunc<string, float, bool> ProcessingBinary = null;

//        public event GameFrameworkAction<Platform> ProcessResourceComplete = null;

//        public event GameFrameworkAction<string> BuildResourceError = null;

//        public bool Load()
//        {
//            if (!File.Exists(m_ConfigurationPath))
//            {
//                return false;
//            }

//            try
//            {
//                XmlDocument xmlDocument = new XmlDocument();
//                xmlDocument.Load(m_ConfigurationPath);
//                XmlNode xmlRoot = xmlDocument.SelectSingleNode("UnityGameFramework");
//                XmlNode xmlEditor = xmlRoot.SelectSingleNode("ResourceBuilder");
//                XmlNode xmlSettings = xmlEditor.SelectSingleNode("Settings");

//                XmlNodeList xmlNodeList = null;
//                XmlNode xmlNode = null;

//                xmlNodeList = xmlSettings.ChildNodes;
//                for (int i = 0; i < xmlNodeList.Count; i++)
//                {
//                    xmlNode = xmlNodeList.Item(i);
//                    switch (xmlNode.Name)
//                    {
//                        case "InternalResourceVersion":
//                            InternalResourceVersion = int.Parse(xmlNode.InnerText) + 1;
//                            break;

//                        case "Platforms":
//                            Platforms = (Platform)int.Parse(xmlNode.InnerText);
//                            break;

//                        case "AssetBundleCompression":
//                            AssetBundleCompression = (AssetBundleCompressionType)byte.Parse(xmlNode.InnerText);
//                            break;

//                        case "CompressionHelperTypeName":
//                            CompressionHelperTypeName = xmlNode.InnerText;
//                            break;

//                        case "AdditionalCompressionSelected":
//                            AdditionalCompressionSelected = bool.Parse(xmlNode.InnerText);
//                            break;

//                        case "ForceRebuildAssetBundleSelected":
//                            ForceRebuildAssetBundleSelected = bool.Parse(xmlNode.InnerText);
//                            break;

//                        case "BuildEventHandlerTypeName":
//                            BuildEventHandlerTypeName = xmlNode.InnerText;
//                            break;

//                        case "OutputDirectory":
//                            OutputDirectory = xmlNode.InnerText;
//                            break;

//                        case "OutputPackageSelected":
//                            OutputPackageSelected = bool.Parse(xmlNode.InnerText);
//                            break;

//                        case "OutputFullSelected":
//                            OutputFullSelected = bool.Parse(xmlNode.InnerText);
//                            break;

//                        case "OutputPackedSelected":
//                            OutputPackedSelected = bool.Parse(xmlNode.InnerText);
//                            break;
//                    }
//                }
//            }
//            catch
//            {
//                File.Delete(m_ConfigurationPath);
//                return false;
//            }

//            return true;
//        }

//        public bool Save()
//        {
//            try
//            {
//                XmlDocument xmlDocument = new XmlDocument();
//                xmlDocument.AppendChild(xmlDocument.CreateXmlDeclaration("1.0", "UTF-8", null));

//                XmlElement xmlRoot = xmlDocument.CreateElement("UnityGameFramework");
//                xmlDocument.AppendChild(xmlRoot);

//                XmlElement xmlBuilder = xmlDocument.CreateElement("ResourceBuilder");
//                xmlRoot.AppendChild(xmlBuilder);

//                XmlElement xmlSettings = xmlDocument.CreateElement("Settings");
//                xmlBuilder.AppendChild(xmlSettings);

//                XmlElement xmlElement = null;

//                xmlElement = xmlDocument.CreateElement("InternalResourceVersion");
//                xmlElement.InnerText = InternalResourceVersion.ToString();
//                xmlSettings.AppendChild(xmlElement);
//                xmlElement = xmlDocument.CreateElement("Platforms");
//                xmlElement.InnerText = ((int)Platforms).ToString();
//                xmlSettings.AppendChild(xmlElement);
//                xmlElement = xmlDocument.CreateElement("AssetBundleCompression");
//                xmlElement.InnerText = ((byte)AssetBundleCompression).ToString();
//                xmlSettings.AppendChild(xmlElement);
//                xmlElement = xmlDocument.CreateElement("CompressionHelperTypeName");
//                xmlElement.InnerText = CompressionHelperTypeName;
//                xmlSettings.AppendChild(xmlElement);
//                xmlElement = xmlDocument.CreateElement("AdditionalCompressionSelected");
//                xmlElement.InnerText = AdditionalCompressionSelected.ToString();
//                xmlSettings.AppendChild(xmlElement);
//                xmlElement = xmlDocument.CreateElement("ForceRebuildAssetBundleSelected");
//                xmlElement.InnerText = ForceRebuildAssetBundleSelected.ToString();
//                xmlSettings.AppendChild(xmlElement);
//                xmlElement = xmlDocument.CreateElement("BuildEventHandlerTypeName");
//                xmlElement.InnerText = BuildEventHandlerTypeName;
//                xmlSettings.AppendChild(xmlElement);
//                xmlElement = xmlDocument.CreateElement("OutputDirectory");
//                xmlElement.InnerText = OutputDirectory;
//                xmlSettings.AppendChild(xmlElement);
//                xmlElement = xmlDocument.CreateElement("OutputPackageSelected");
//                xmlElement.InnerText = OutputPackageSelected.ToString();
//                xmlSettings.AppendChild(xmlElement);
//                xmlElement = xmlDocument.CreateElement("OutputFullSelected");
//                xmlElement.InnerText = OutputFullSelected.ToString();
//                xmlSettings.AppendChild(xmlElement);
//                xmlElement = xmlDocument.CreateElement("OutputPackedSelected");
//                xmlElement.InnerText = OutputPackedSelected.ToString();
//                xmlSettings.AppendChild(xmlElement);

//                string configurationDirectoryName = Path.GetDirectoryName(m_ConfigurationPath);
//                if (!Directory.Exists(configurationDirectoryName))
//                {
//                    Directory.CreateDirectory(configurationDirectoryName);
//                }

//                xmlDocument.Save(m_ConfigurationPath);
//                AssetDatabase.Refresh();
//                return true;
//            }
//            catch
//            {
//                if (File.Exists(m_ConfigurationPath))
//                {
//                    File.Delete(m_ConfigurationPath);
//                }

//                return false;
//            }
//        }

//        public string[] GetCompressionHelperTypeNames()
//        {
//            return m_CompressionHelperTypeNames.ToArray();
//        }

//        public string[] GetBuildEventHandlerTypeNames()
//        {
//            return m_BuildEventHandlerTypeNames.ToArray();
//        }

//        public bool IsPlatformSelected(Platform platform)
//        {
//            return (Platforms & platform) != 0;
//        }

//        public void SelectPlatform(Platform platform, bool selected)
//        {
//            if (selected)
//            {
//                Platforms |= platform;
//            }
//            else
//            {
//                Platforms &= ~platform;
//            }
//        }

//        public bool RefreshCompressionHelper()
//        {
//            bool retVal = false;
//            if (!string.IsNullOrEmpty(CompressionHelperTypeName) && m_CompressionHelperTypeNames.Contains(CompressionHelperTypeName))
//            {
//                System.Type compressionHelperType = Utility.Assembly.GetType(CompressionHelperTypeName);
//                if (compressionHelperType != null)
//                {
//                    Utility.Compression.ICompressionHelper compressionHelper = (Utility.Compression.ICompressionHelper)Activator.CreateInstance(compressionHelperType);
//                    if (compressionHelper != null)
//                    {
//                        Utility.Compression.SetCompressionHelper(compressionHelper);
//                        return true;
//                    }
//                }
//            }
//            else
//            {
//                retVal = true;
//            }

//            CompressionHelperTypeName = string.Empty;
//            Utility.Compression.SetCompressionHelper(null);
//            return retVal;
//        }

//        public bool RefreshBuildEventHandler()
//        {
//            bool retVal = false;
//            if (!string.IsNullOrEmpty(BuildEventHandlerTypeName) && m_BuildEventHandlerTypeNames.Contains(BuildEventHandlerTypeName))
//            {
//                System.Type buildEventHandlerType = Utility.Assembly.GetType(BuildEventHandlerTypeName);
//                if (buildEventHandlerType != null)
//                {
//                    IBuildEventHandler buildEventHandler = (IBuildEventHandler)Activator.CreateInstance(buildEventHandlerType);
//                    if (buildEventHandler != null)
//                    {
//                        m_BuildEventHandler = buildEventHandler;
//                        return true;
//                    }
//                }
//            }
//            else
//            {
//                retVal = true;
//            }

//            BuildEventHandlerTypeName = string.Empty;
//            m_BuildEventHandler = null;
//            return retVal;
//        }

//        public bool BuildResources()
//        {
//            if (!IsValidOutputDirectory)
//            {
//                return false;
//            }

//            if (Directory.Exists(OutputPackagePath))
//            {
//                Directory.Delete(OutputPackagePath, true);
//            }

//            Directory.CreateDirectory(OutputPackagePath);

//            if (Directory.Exists(OutputFullPath))
//            {
//                Directory.Delete(OutputFullPath, true);
//            }

//            Directory.CreateDirectory(OutputFullPath);

//            if (Directory.Exists(OutputPackedPath))
//            {
//                Directory.Delete(OutputPackedPath, true);
//            }

//            Directory.CreateDirectory(OutputPackedPath);

//            if (Directory.Exists(BuildReportPath))
//            {
//                Directory.Delete(BuildReportPath, true);
//            }

//            Directory.CreateDirectory(BuildReportPath);

//            BuildAssetBundleOptions buildAssetBundleOptions = GetBuildAssetBundleOptions();
//            m_BuildReport.Initialize(BuildReportPath, ProductName, CompanyName, GameIdentifier, GameFrameworkVersion, UnityVersion, ApplicableGameVersion, InternalResourceVersion,
//                Platforms, AssetBundleCompression, CompressionHelperTypeName, AdditionalCompressionSelected, ForceRebuildAssetBundleSelected, BuildEventHandlerTypeName, OutputDirectory, buildAssetBundleOptions, m_ResourceDatas);

//            try
//            {
//                m_BuildReport.LogInfo("Build Start Time: {0:yyyy-MM-dd HH:mm:ss.fff}", DateTime.UtcNow.ToLocalTime());

//                if (m_BuildEventHandler != null)
//                {
//                    m_BuildReport.LogInfo("Execute build event handler 'OnPreprocessAllPlatforms'...");
//                    m_BuildEventHandler.OnPreprocessAllPlatforms(ProductName, CompanyName, GameIdentifier, GameFrameworkVersion, UnityVersion, ApplicableGameVersion, InternalResourceVersion,
//                        Platforms, AssetBundleCompression, CompressionHelperTypeName, AdditionalCompressionSelected, ForceRebuildAssetBundleSelected, BuildEventHandlerTypeName, OutputDirectory, buildAssetBundleOptions,
//                        WorkingPath, OutputPackageSelected, OutputPackagePath, OutputFullSelected, OutputFullPath, OutputPackedSelected, OutputPackedPath, BuildReportPath);
//                }

//                m_BuildReport.LogInfo("Start prepare resource collection...");
//                if (!m_ResourceCollection.Load())
//                {
//                    m_BuildReport.LogError("Can not parse 'ResourceCollection.xml', please use 'Resource Editor' tool first.");

//                    if (m_BuildEventHandler != null)
//                    {
//                        m_BuildReport.LogInfo("Execute build event handler 'OnPostprocessAllPlatforms'...");
//                        m_BuildEventHandler.OnPostprocessAllPlatforms(ProductName, CompanyName, GameIdentifier, GameFrameworkVersion, UnityVersion, ApplicableGameVersion, InternalResourceVersion,
//                            Platforms, AssetBundleCompression, CompressionHelperTypeName, AdditionalCompressionSelected, ForceRebuildAssetBundleSelected, BuildEventHandlerTypeName, OutputDirectory, buildAssetBundleOptions,
//                            WorkingPath, OutputPackageSelected, OutputPackagePath, OutputFullSelected, OutputFullPath, OutputPackedSelected, OutputPackedPath, BuildReportPath);
//                    }

//                    m_BuildReport.SaveReport();
//                    return false;
//                }

//                if (Platforms == Platform.Undefined)
//                {
//                    m_BuildReport.LogError("Platform undefined.");

//                    if (m_BuildEventHandler != null)
//                    {
//                        m_BuildReport.LogInfo("Execute build event handler 'OnPostprocessAllPlatforms'...");
//                        m_BuildEventHandler.OnPostprocessAllPlatforms(ProductName, CompanyName, GameIdentifier, GameFrameworkVersion, UnityVersion, ApplicableGameVersion, InternalResourceVersion,
//                            Platforms, AssetBundleCompression, CompressionHelperTypeName, AdditionalCompressionSelected, ForceRebuildAssetBundleSelected, BuildEventHandlerTypeName, OutputDirectory, buildAssetBundleOptions,
//                            WorkingPath, OutputPackageSelected, OutputPackagePath, OutputFullSelected, OutputFullPath, OutputPackedSelected, OutputPackedPath, BuildReportPath);
//                    }

//                    m_BuildReport.SaveReport();
//                    return false;
//                }

//                m_BuildReport.LogInfo("Prepare resource collection complete.");
//                m_BuildReport.LogInfo("Start analyze assets dependency...");

//                m_ResourceAnalyzerController.Analyze();

//                m_BuildReport.LogInfo("Analyze assets dependency complete.");
//                m_BuildReport.LogInfo("Start prepare build data...");

//                AssetBundleBuild[] assetBundleBuildDatas = null;
//                ResourceData[] assetBundleResourceDatas = null;
//                ResourceData[] binaryResourceDatas = null;
//                if (!PrepareBuildData(out assetBundleBuildDatas, out assetBundleResourceDatas, out binaryResourceDatas))
//                {
//                    m_BuildReport.LogError("Prepare resource build data failure.");

//                    if (m_BuildEventHandler != null)
//                    {
//                        m_BuildReport.LogInfo("Execute build event handler 'OnPostprocessAllPlatforms'...");
//                        m_BuildEventHandler.OnPostprocessAllPlatforms(ProductName, CompanyName, GameIdentifier, GameFrameworkVersion, UnityVersion, ApplicableGameVersion, InternalResourceVersion,
//                            Platforms, AssetBundleCompression, CompressionHelperTypeName, AdditionalCompressionSelected, ForceRebuildAssetBundleSelected, BuildEventHandlerTypeName, OutputDirectory, buildAssetBundleOptions,
//                            WorkingPath, OutputPackageSelected, OutputPackagePath, OutputFullSelected, OutputFullPath, OutputPackedSelected, OutputPackedPath, BuildReportPath);
//                    }

//                    m_BuildReport.SaveReport();
//                    return false;
//                }

//                m_BuildReport.LogInfo("Prepare resource build data complete.");
//                m_BuildReport.LogInfo("Start build resources for selected platforms...");

//                bool watchResult = m_BuildEventHandler == null || !m_BuildEventHandler.ContinueOnFailure;
//                bool isSuccess = false;
//                isSuccess = BuildResources(Platform.Windows, assetBundleBuildDatas, buildAssetBundleOptions, assetBundleResourceDatas, binaryResourceDatas);

//                if (!watchResult || isSuccess)
//                {
//                    isSuccess = BuildResources(Platform.Windows64, assetBundleBuildDatas, buildAssetBundleOptions, assetBundleResourceDatas, binaryResourceDatas);
//                }

//                if (!watchResult || isSuccess)
//                {
//                    isSuccess = BuildResources(Platform.MacOS, assetBundleBuildDatas, buildAssetBundleOptions, assetBundleResourceDatas, binaryResourceDatas);
//                }

//                if (!watchResult || isSuccess)
//                {
//                    isSuccess = BuildResources(Platform.Linux, assetBundleBuildDatas, buildAssetBundleOptions, assetBundleResourceDatas, binaryResourceDatas);
//                }

//                if (!watchResult || isSuccess)
//                {
//                    isSuccess = BuildResources(Platform.IOS, assetBundleBuildDatas, buildAssetBundleOptions, assetBundleResourceDatas, binaryResourceDatas);
//                }

//                if (!watchResult || isSuccess)
//                {
//                    isSuccess = BuildResources(Platform.Android, assetBundleBuildDatas, buildAssetBundleOptions, assetBundleResourceDatas, binaryResourceDatas);
//                }

//                if (!watchResult || isSuccess)
//                {
//                    isSuccess = BuildResources(Platform.WindowsStore, assetBundleBuildDatas, buildAssetBundleOptions, assetBundleResourceDatas, binaryResourceDatas);
//                }

//                if (!watchResult || isSuccess)
//                {
//                    isSuccess = BuildResources(Platform.WebGL, assetBundleBuildDatas, buildAssetBundleOptions, assetBundleResourceDatas, binaryResourceDatas);
//                }

//                if (m_BuildEventHandler != null)
//                {
//                    m_BuildReport.LogInfo("Execute build event handler 'OnPostprocessAllPlatforms'...");
//                    m_BuildEventHandler.OnPostprocessAllPlatforms(ProductName, CompanyName, GameIdentifier, GameFrameworkVersion, UnityVersion, ApplicableGameVersion, InternalResourceVersion,
//                        Platforms, AssetBundleCompression, CompressionHelperTypeName, AdditionalCompressionSelected, ForceRebuildAssetBundleSelected, BuildEventHandlerTypeName, OutputDirectory, buildAssetBundleOptions,
//                        WorkingPath, OutputPackageSelected, OutputPackagePath, OutputFullSelected, OutputFullPath, OutputPackedSelected, OutputPackedPath, BuildReportPath);
//                }

//                m_BuildReport.LogInfo("Build resources for selected platforms complete.");
//                m_BuildReport.SaveReport();

//                return true;
//            }
//            catch (Exception exception)
//            {
//                string errorMessage = exception.ToString();
//                m_BuildReport.LogFatal(errorMessage);
//                m_BuildReport.SaveReport();
//                if (BuildResourceError != null)
//                {
//                    BuildResourceError(errorMessage);
//                }

//                return false;
//            }
//            finally
//            {
//                m_OutputPackageFileSystems.Clear();
//                m_OutputPackedFileSystems.Clear();
//                if (m_FileSystemManager != null)
//                {
//                    GameFrameworkEntry.Shutdown();
//                    m_FileSystemManager = null;
//                }
//            }
//        }

//        private bool BuildResources(Platform platform, AssetBundleBuild[] assetBundleBuildDatas, BuildAssetBundleOptions buildAssetBundleOptions, ResourceData[] assetBundleResourceDatas, ResourceData[] binaryResourceDatas)
//        {
//            if (!IsPlatformSelected(platform))
//            {
//                return true;
//            }

//            string platformName = platform.ToString();
//            m_BuildReport.LogInfo("Start build resources for '{0}'...", platformName);

//            string workingPath = Utility.Text.Format("{0}{1}/", WorkingPath, platformName);
//            m_BuildReport.LogInfo("Working path is '{0}'.", workingPath);

//            string outputPackagePath = Utility.Text.Format("{0}{1}/", OutputPackagePath, platformName);
//            if (OutputPackageSelected)
//            {
//                Directory.CreateDirectory(outputPackagePath);
//                m_BuildReport.LogInfo("Output package is selected, path is '{0}'.", outputPackagePath);
//            }
//            else
//            {
//                m_BuildReport.LogInfo("Output package is not selected.");
//            }

//            string outputFullPath = Utility.Text.Format("{0}{1}/", OutputFullPath, platformName);
//            if (OutputFullSelected)
//            {
//                Directory.CreateDirectory(outputFullPath);
//                m_BuildReport.LogInfo("Output full is selected, path is '{0}'.", outputFullPath);
//            }
//            else
//            {
//                m_BuildReport.LogInfo("Output full is not selected.");
//            }

//            string outputPackedPath = Utility.Text.Format("{0}{1}/", OutputPackedPath, platformName);
//            if (OutputPackedSelected)
//            {
//                Directory.CreateDirectory(outputPackedPath);
//                m_BuildReport.LogInfo("Output packed is selected, path is '{0}'.", outputPackedPath);
//            }
//            else
//            {
//                m_BuildReport.LogInfo("Output packed is not selected.");
//            }

//            // Clean working path
//            List<string> validNames = new List<string>();
//            foreach (ResourceData assetBundleResourceData in assetBundleResourceDatas)
//            {
//                validNames.Add(GetResourceFullName(assetBundleResourceData.Name, assetBundleResourceData.Variant).ToLowerInvariant());
//            }

//            if (Directory.Exists(workingPath))
//            {
//                Uri workingUri = new Uri(workingPath, UriKind.Absolute);
//                string[] fileNames = Directory.GetFiles(workingPath, "*", SearchOption.AllDirectories);
//                foreach (string fileName in fileNames)
//                {
//                    if (fileName.EndsWith(".manifest", StringComparison.Ordinal))
//                    {
//                        continue;
//                    }

//                    string relativeName = workingUri.MakeRelativeUri(new Uri(fileName, UriKind.Absolute)).ToString();
//                    if (!validNames.Contains(relativeName))
//                    {
//                        File.Delete(fileName);
//                    }
//                }

//                string[] manifestNames = Directory.GetFiles(workingPath, "*.manifest", SearchOption.AllDirectories);
//                foreach (string manifestName in manifestNames)
//                {
//                    if (!File.Exists(manifestName.Substring(0, manifestName.LastIndexOf('.'))))
//                    {
//                        File.Delete(manifestName);
//                    }
//                }

//                Utility.Path.RemoveEmptyDirectory(workingPath);
//            }

//            if (!Directory.Exists(workingPath))
//            {
//                Directory.CreateDirectory(workingPath);
//            }

//            if (m_BuildEventHandler != null)
//            {
//                m_BuildReport.LogInfo("Execute build event handler 'OnPreprocessPlatform' for '{0}'...", platformName);
//                m_BuildEventHandler.OnPreprocessPlatform(platform, workingPath, OutputPackageSelected, outputPackagePath, OutputFullSelected, outputFullPath, OutputPackedSelected, outputPackedPath);
//            }

//            // Build AssetBundles
//            m_BuildReport.LogInfo("Unity start build asset bundles for '{0}'...", platformName);
//            AssetBundleManifest assetBundleManifest = BuildPipeline.BuildAssetBundles(workingPath, assetBundleBuildDatas, buildAssetBundleOptions, GetBuildTarget(platform));
//            if (assetBundleManifest == null)
//            {
//                m_BuildReport.LogError("Build asset bundles for '{0}' failure.", platformName);

//                if (m_BuildEventHandler != null)
//                {
//                    m_BuildReport.LogInfo("Execute build event handler 'OnPostprocessPlatform' for '{0}'...", platformName);
//                    m_BuildEventHandler.OnPostprocessPlatform(platform, workingPath, OutputPackageSelected, outputPackagePath, OutputFullSelected, outputFullPath, OutputPackedSelected, outputPackedPath, false);
//                }

//                return false;
//            }

//            if (m_BuildEventHandler != null)
//            {
//                m_BuildReport.LogInfo("Execute build event handler 'OnBuildAssetBundlesComplete' for '{0}'...", platformName);
//                m_BuildEventHandler.OnBuildAssetBundlesComplete(platform, workingPath, OutputPackageSelected, outputPackagePath, OutputFullSelected, outputFullPath, OutputPackedSelected, outputPackedPath, assetBundleManifest);
//            }

//            m_BuildReport.LogInfo("Unity build asset bundles for '{0}' complete.", platformName);

//            // Create FileSystems
//            m_BuildReport.LogInfo("Start create file system for '{0}'...", platformName);

//            if (OutputPackageSelected)
//            {
//                CreateFileSystems(m_ResourceDatas.Values, outputPackagePath, m_OutputPackageFileSystems);
//            }

//            if (OutputPackedSelected)
//            {
//                CreateFileSystems(GetPackedResourceDatas(), outputPackedPath, m_OutputPackedFileSystems);
//            }

//            m_BuildReport.LogInfo("Create file system for '{0}' complete.", platformName);

//            // Process AssetBundles
//            for (int i = 0; i < assetBundleResourceDatas.Length; i++)
//            {
//                string fullName = GetResourceFullName(assetBundleResourceDatas[i].Name, assetBundleResourceDatas[i].Variant);
//                if (ProcessingAssetBundle != null)
//                {
//                    if (ProcessingAssetBundle(fullName, (float)(i + 1) / assetBundleResourceDatas.Length))
//                    {
//                        m_BuildReport.LogWarning("The build has been canceled by user.");

//                        if (m_BuildEventHandler != null)
//                        {
//                            m_BuildReport.LogInfo("Execute build event handler 'OnPostprocessPlatform' for '{0}'...", platformName);
//                            m_BuildEventHandler.OnPostprocessPlatform(platform, workingPath, OutputPackageSelected, outputPackagePath, OutputFullSelected, outputFullPath, OutputPackedSelected, outputPackedPath, false);
//                        }

//                        return false;
//                    }
//                }

//                m_BuildReport.LogInfo("Start process asset bundle '{0}' for '{1}'...", fullName, platformName);

//                if (!ProcessAssetBundle(platform, workingPath, outputPackagePath, outputFullPath, outputPackedPath, AdditionalCompressionSelected, assetBundleResourceDatas[i].Name, assetBundleResourceDatas[i].Variant, assetBundleResourceDatas[i].FileSystem))
//                {
//                    return false;
//                }

//                m_BuildReport.LogInfo("Process asset bundle '{0}' for '{1}' complete.", fullName, platformName);
//            }

//            // Process Binaries
//            for (int i = 0; i < binaryResourceDatas.Length; i++)
//            {
//                string fullName = GetResourceFullName(binaryResourceDatas[i].Name, binaryResourceDatas[i].Variant);
//                if (ProcessingBinary != null)
//                {
//                    if (ProcessingBinary(fullName, (float)(i + 1) / binaryResourceDatas.Length))
//                    {
//                        m_BuildReport.LogWarning("The build has been canceled by user.");

//                        if (m_BuildEventHandler != null)
//                        {
//                            m_BuildReport.LogInfo("Execute build event handler 'OnPostprocessPlatform' for '{0}'...", platformName);
//                            m_BuildEventHandler.OnPostprocessPlatform(platform, workingPath, OutputPackageSelected, outputPackagePath, OutputFullSelected, outputFullPath, OutputPackedSelected, outputPackedPath, false);
//                        }

//                        return false;
//                    }
//                }

//                m_BuildReport.LogInfo("Start process binary '{0}' for '{1}'...", fullName, platformName);

//                if (!ProcessBinary(platform, workingPath, outputPackagePath, outputFullPath, outputPackedPath, AdditionalCompressionSelected, binaryResourceDatas[i].Name, binaryResourceDatas[i].Variant, binaryResourceDatas[i].FileSystem))
//                {
//                    return false;
//                }

//                m_BuildReport.LogInfo("Process binary '{0}' for '{1}' complete.", fullName, platformName);
//            }

//            if (OutputPackageSelected)
//            {
//                ProcessPackageVersionList(outputPackagePath, platform);
//                m_BuildReport.LogInfo("Process package version list for '{0}' complete.", platformName);
//            }

//            if (OutputFullSelected)
//            {
//                VersionListData versionListData = ProcessUpdatableVersionList(outputFullPath, platform);
//                m_BuildReport.LogInfo("Process updatable version list for '{0}' complete, updatable version list path is '{1}', length is '{2}', hash code is '{3}[0x{3:X8}]', compressed length is '{4}', compressed hash code is '{5}[0x{5:X8}]'.", platformName, versionListData.Path, versionListData.Length, versionListData.HashCode, versionListData.CompressedLength, versionListData.CompressedHashCode);
//                if (m_BuildEventHandler != null)
//                {
//                    m_BuildReport.LogInfo("Execute build event handler 'OnOutputUpdatableVersionListData' for '{0}'...", platformName);
//                    m_BuildEventHandler.OnOutputUpdatableVersionListData(platform, versionListData.Path, versionListData.Length, versionListData.HashCode, versionListData.CompressedLength, versionListData.CompressedHashCode);
//                }
//            }

//            if (OutputPackedSelected)
//            {
//                ProcessReadOnlyVersionList(outputPackedPath, platform);
//                m_BuildReport.LogInfo("Process read-only version list for '{0}' complete.", platformName);
//            }

//            if (m_BuildEventHandler != null)
//            {
//                m_BuildReport.LogInfo("Execute build event handler 'OnPostprocessPlatform' for '{0}'...", platformName);
//                m_BuildEventHandler.OnPostprocessPlatform(platform, workingPath, OutputPackageSelected, outputPackagePath, OutputFullSelected, outputFullPath, OutputPackedSelected, outputPackedPath, true);
//            }

//            if (ProcessResourceComplete != null)
//            {
//                ProcessResourceComplete(platform);
//            }

//            m_BuildReport.LogInfo("Build resources for '{0}' success.", platformName);
//            return true;
//        }

//        private bool ProcessAssetBundle(Platform platform, string workingPath, string outputPackagePath, string outputFullPath, string outputPackedPath, bool additionalCompressionSelected, string name, string variant, string fileSystem)
//        {
//            string fullName = GetResourceFullName(name, variant);
//            ResourceData resourceData = m_ResourceDatas[fullName];
//            string workingName = Utility.Path.GetRegularPath(Path.Combine(workingPath, fullName.ToLowerInvariant()));

//            byte[] bytes = File.ReadAllBytes(workingName);
//            int length = bytes.Length;
//            int hashCode = Utility.Verifier.GetCrc32(bytes);
//            int compressedLength = length;
//            int compressedHashCode = hashCode;

//            byte[] hashBytes = Utility.Converter.GetBytes(hashCode);
//            if (resourceData.LoadType == LoadType.LoadFromMemoryAndQuickDecrypt)
//            {
//                bytes = Utility.Encryption.GetQuickXorBytes(bytes, hashBytes);
//            }
//            else if (resourceData.LoadType == LoadType.LoadFromMemoryAndDecrypt)
//            {
//                bytes = Utility.Encryption.GetXorBytes(bytes, hashBytes);
//            }

//            return ProcessOutput(platform, outputPackagePath, outputFullPath, outputPackedPath, additionalCompressionSelected, name, variant, fileSystem, resourceData, bytes, length, hashCode, compressedLength, compressedHashCode);
//        }

//        private bool ProcessBinary(Platform platform, string workingPath, string outputPackagePath, string outputFullPath, string outputPackedPath, bool additionalCompressionSelected, string name, string variant, string fileSystem)
//        {
//            string fullName = GetResourceFullName(name, variant);
//            ResourceData resourceData = m_ResourceDatas[fullName];
//            string assetName = resourceData.GetAssetNames()[0];
//            string assetPath = Utility.Path.GetRegularPath(Application.dataPath.Substring(0, Application.dataPath.Length - AssetsStringLength) + assetName);

//            byte[] bytes = File.ReadAllBytes(assetPath);
//            int length = bytes.Length;
//            int hashCode = Utility.Verifier.GetCrc32(bytes);
//            int compressedLength = length;
//            int compressedHashCode = hashCode;

//            byte[] hashBytes = Utility.Converter.GetBytes(hashCode);
//            if (resourceData.LoadType == LoadType.LoadFromBinaryAndQuickDecrypt)
//            {
//                bytes = Utility.Encryption.GetQuickXorBytes(bytes, hashBytes);
//            }
//            else if (resourceData.LoadType == LoadType.LoadFromBinaryAndDecrypt)
//            {
//                bytes = Utility.Encryption.GetXorBytes(bytes, hashBytes);
//            }

//            return ProcessOutput(platform, outputPackagePath, outputFullPath, outputPackedPath, additionalCompressionSelected, name, variant, fileSystem, resourceData, bytes, length, hashCode, compressedLength, compressedHashCode);
//        }

//        private void ProcessPackageVersionList(string outputPackagePath, Platform platform)
//        {
//            Asset[] originalAssets = m_ResourceCollection.GetAssets();
//            PackageVersionList.Asset[] assets = new PackageVersionList.Asset[originalAssets.Length];
//            for (int i = 0; i < assets.Length; i++)
//            {
//                Asset originalAsset = originalAssets[i];
//                assets[i] = new PackageVersionList.Asset(originalAsset.Name, GetDependencyAssetIndexes(originalAsset.Name));
//            }

//            SortedDictionary<string, ResourceData>.ValueCollection resourceDatas = m_ResourceDatas.Values;

//            int index = 0;
//            PackageVersionList.Resource[] resources = new PackageVersionList.Resource[m_ResourceCollection.ResourceCount];
//            foreach (ResourceData resourceData in resourceDatas)
//            {
//                ResourceCode resourceCode = resourceData.GetCode(platform);
//                resources[index++] = new PackageVersionList.Resource(resourceData.Name, resourceData.Variant, GetExtension(resourceData), (byte)resourceData.LoadType, resourceCode.Length, resourceCode.HashCode, GetAssetIndexes(resourceData));
//            }

//            string[] fileSystemNames = GetFileSystemNames(resourceDatas);
//            PackageVersionList.FileSystem[] fileSystems = new PackageVersionList.FileSystem[fileSystemNames.Length];
//            for (int i = 0; i < fileSystems.Length; i++)
//            {
//                fileSystems[i] = new PackageVersionList.FileSystem(fileSystemNames[i], GetResourceIndexesFromFileSystem(resourceDatas, fileSystemNames[i]));
//            }

//            string[] resourceGroupNames = GetResourceGroupNames(resourceDatas);
//            PackageVersionList.ResourceGroup[] resourceGroups = new PackageVersionList.ResourceGroup[resourceGroupNames.Length];
//            for (int i = 0; i < resourceGroups.Length; i++)
//            {
//                resourceGroups[i] = new PackageVersionList.ResourceGroup(resourceGroupNames[i], GetResourceIndexesFromResourceGroup(resourceDatas, resourceGroupNames[i]));
//            }

//            PackageVersionList versionList = new PackageVersionList(ApplicableGameVersion, InternalResourceVersion, assets, resources, fileSystems, resourceGroups);
//            PackageVersionListSerializer serializer = new PackageVersionListSerializer();
//            serializer.RegisterSerializeCallback(0, BuiltinVersionListSerializer.PackageVersionListSerializeCallback_V0);
//            serializer.RegisterSerializeCallback(1, BuiltinVersionListSerializer.PackageVersionListSerializeCallback_V1);
//            serializer.RegisterSerializeCallback(2, BuiltinVersionListSerializer.PackageVersionListSerializeCallback_V2);
//            string packageVersionListPath = Utility.Path.GetRegularPath(Path.Combine(outputPackagePath, RemoteVersionListFileName));
//            using (FileStream fileStream = new FileStream(packageVersionListPath, FileMode.Create, FileAccess.Write))
//            {
//                if (!serializer.Serialize(fileStream, versionList))
//                {
//                    throw new GameFrameworkException("Serialize package version list failure.");
//                }
//            }
//        }

//        private VersionListData ProcessUpdatableVersionList(string outputFullPath, Platform platform)
//        {
//            Asset[] originalAssets = m_ResourceCollection.GetAssets();
//            UpdatableVersionList.Asset[] assets = new UpdatableVersionList.Asset[originalAssets.Length];
//            for (int i = 0; i < assets.Length; i++)
//            {
//                Asset originalAsset = originalAssets[i];
//                assets[i] = new UpdatableVersionList.Asset(originalAsset.Name, GetDependencyAssetIndexes(originalAsset.Name));
//            }

//            SortedDictionary<string, ResourceData>.ValueCollection resourceDatas = m_ResourceDatas.Values;

//            int index = 0;
//            UpdatableVersionList.Resource[] resources = new UpdatableVersionList.Resource[m_ResourceCollection.ResourceCount];
//            foreach (ResourceData resourceData in resourceDatas)
//            {
//                ResourceCode resourceCode = resourceData.GetCode(platform);
//                resources[index++] = new UpdatableVersionList.Resource(resourceData.Name, resourceData.Variant, GetExtension(resourceData), (byte)resourceData.LoadType, resourceCode.Length, resourceCode.HashCode, resourceCode.CompressedLength, resourceCode.CompressedHashCode, GetAssetIndexes(resourceData));
//            }

//            string[] fileSystemNames = GetFileSystemNames(resourceDatas);
//            UpdatableVersionList.FileSystem[] fileSystems = new UpdatableVersionList.FileSystem[fileSystemNames.Length];
//            for (int i = 0; i < fileSystems.Length; i++)
//            {
//                fileSystems[i] = new UpdatableVersionList.FileSystem(fileSystemNames[i], GetResourceIndexesFromFileSystem(resourceDatas, fileSystemNames[i]));
//            }

//            string[] resourceGroupNames = GetResourceGroupNames(resourceDatas);
//            UpdatableVersionList.ResourceGroup[] resourceGroups = new UpdatableVersionList.ResourceGroup[resourceGroupNames.Length];
//            for (int i = 0; i < resourceGroups.Length; i++)
//            {
//                resourceGroups[i] = new UpdatableVersionList.ResourceGroup(resourceGroupNames[i], GetResourceIndexesFromResourceGroup(resourceDatas, resourceGroupNames[i]));
//            }

//            UpdatableVersionList versionList = new UpdatableVersionList(ApplicableGameVersion, InternalResourceVersion, assets, resources, fileSystems, resourceGroups);
//            UpdatableVersionListSerializer serializer = new UpdatableVersionListSerializer();
//            serializer.RegisterSerializeCallback(0, BuiltinVersionListSerializer.UpdatableVersionListSerializeCallback_V0);
//            serializer.RegisterSerializeCallback(1, BuiltinVersionListSerializer.UpdatableVersionListSerializeCallback_V1);
//            serializer.RegisterSerializeCallback(2, BuiltinVersionListSerializer.UpdatableVersionListSerializeCallback_V2);
//            string updatableVersionListPath = Utility.Path.GetRegularPath(Path.Combine(outputFullPath, RemoteVersionListFileName));
//            using (FileStream fileStream = new FileStream(updatableVersionListPath, FileMode.Create, FileAccess.Write))
//            {
//                if (!serializer.Serialize(fileStream, versionList))
//                {
//                    throw new GameFrameworkException("Serialize updatable version list failure.");
//                }
//            }

//            byte[] bytes = File.ReadAllBytes(updatableVersionListPath);
//            int length = bytes.Length;
//            int hashCode = Utility.Verifier.GetCrc32(bytes);
//            bytes = Utility.Compression.Compress(bytes);
//            int compressedLength = bytes.Length;
//            File.WriteAllBytes(updatableVersionListPath, bytes);
//            int compressedHashCode = Utility.Verifier.GetCrc32(bytes);
//            int dotPosition = RemoteVersionListFileName.LastIndexOf('.');
//            string versionListFullNameWithCrc32 = Utility.Text.Format("{0}.{2:x8}.{1}", RemoteVersionListFileName.Substring(0, dotPosition), RemoteVersionListFileName.Substring(dotPosition + 1), hashCode);
//            string updatableVersionListPathWithCrc32 = Utility.Path.GetRegularPath(Path.Combine(outputFullPath, versionListFullNameWithCrc32));
//            File.Move(updatableVersionListPath, updatableVersionListPathWithCrc32);

//            return new VersionListData(updatableVersionListPathWithCrc32, length, hashCode, compressedLength, compressedHashCode);
//        }

//        private void ProcessReadOnlyVersionList(string outputPackedPath, Platform platform)
//        {
//            ResourceData[] packedResourceDatas = GetPackedResourceDatas();

//            LocalVersionList.Resource[] resources = new LocalVersionList.Resource[packedResourceDatas.Length];
//            for (int i = 0; i < resources.Length; i++)
//            {
//                ResourceData resourceData = packedResourceDatas[i];
//                ResourceCode resourceCode = resourceData.GetCode(platform);
//                resources[i] = new LocalVersionList.Resource(resourceData.Name, resourceData.Variant, GetExtension(resourceData), (byte)resourceData.LoadType, resourceCode.Length, resourceCode.HashCode);
//            }

//            string[] packedFileSystemNames = GetFileSystemNames(packedResourceDatas);
//            LocalVersionList.FileSystem[] fileSystems = new LocalVersionList.FileSystem[packedFileSystemNames.Length];
//            for (int i = 0; i < fileSystems.Length; i++)
//            {
//                fileSystems[i] = new LocalVersionList.FileSystem(packedFileSystemNames[i], GetResourceIndexesFromFileSystem(packedResourceDatas, packedFileSystemNames[i]));
//            }

//            LocalVersionList versionList = new LocalVersionList(resources, fileSystems);
//            ReadOnlyVersionListSerializer serializer = new ReadOnlyVersionListSerializer();
//            serializer.RegisterSerializeCallback(0, BuiltinVersionListSerializer.LocalVersionListSerializeCallback_V0);
//            serializer.RegisterSerializeCallback(1, BuiltinVersionListSerializer.LocalVersionListSerializeCallback_V1);
//            serializer.RegisterSerializeCallback(2, BuiltinVersionListSerializer.LocalVersionListSerializeCallback_V2);
//            string readOnlyVersionListPath = Utility.Path.GetRegularPath(Path.Combine(outputPackedPath, LocalVersionListFileName));
//            using (FileStream fileStream = new FileStream(readOnlyVersionListPath, FileMode.Create, FileAccess.Write))
//            {
//                if (!serializer.Serialize(fileStream, versionList))
//                {
//                    throw new GameFrameworkException("Serialize read-only version list failure.");
//                }
//            }
//        }

//        private int[] GetDependencyAssetIndexes(string assetName)
//        {
//            List<int> dependencyAssetIndexes = new List<int>();
//            Asset[] assets = m_ResourceCollection.GetAssets();
//            DependencyData dependencyData = m_ResourceAnalyzerController.GetDependencyData(assetName);
//            foreach (Asset dependencyAsset in dependencyData.GetDependencyAssets())
//            {
//                for (int i = 0; i < assets.Length; i++)
//                {
//                    if (assets[i] == dependencyAsset)
//                    {
//                        dependencyAssetIndexes.Add(i);
//                        break;
//                    }
//                }
//            }

//            dependencyAssetIndexes.Sort();
//            return dependencyAssetIndexes.ToArray();
//        }

//        private int[] GetAssetIndexes(ResourceData resourceData)
//        {
//            Asset[] assets = m_ResourceCollection.GetAssets();
//            string[] assetGuids = resourceData.GetAssetGuids();
//            int[] assetIndexes = new int[assetGuids.Length];
//            for (int i = 0; i < assetGuids.Length; i++)
//            {
//                assetIndexes[i] = Array.BinarySearch(assets, m_ResourceCollection.GetAsset(assetGuids[i]));
//                if (assetIndexes[i] < 0)
//                {
//                    throw new GameFrameworkException("Asset is invalid.");
//                }
//            }

//            return assetIndexes;
//        }

//        private ResourceData[] GetPackedResourceDatas()
//        {
//            List<ResourceData> packedResourceDatas = new List<ResourceData>();
//            foreach (ResourceData resourceData in m_ResourceDatas.Values)
//            {
//                if (!resourceData.Packed)
//                {
//                    continue;
//                }

//                packedResourceDatas.Add(resourceData);
//            }

//            return packedResourceDatas.ToArray();
//        }

//        private string[] GetFileSystemNames(IEnumerable<ResourceData> resourceDatas)
//        {
//            HashSet<string> fileSystemNames = new HashSet<string>();
//            foreach (ResourceData resourceData in resourceDatas)
//            {
//                if (resourceData.FileSystem == null)
//                {
//                    continue;
//                }

//                fileSystemNames.Add(resourceData.FileSystem);
//            }

//            return fileSystemNames.OrderBy(x => x).ToArray();
//        }

//        private int[] GetResourceIndexesFromFileSystem(IEnumerable<ResourceData> resourceDatas, string fileSystemName)
//        {
//            int index = 0;
//            List<int> resourceIndexes = new List<int>();
//            foreach (ResourceData resourceData in resourceDatas)
//            {
//                if (resourceData.FileSystem == fileSystemName)
//                {
//                    resourceIndexes.Add(index);
//                }

//                index++;
//            }

//            resourceIndexes.Sort();
//            return resourceIndexes.ToArray();
//        }

//        private string[] GetResourceGroupNames(IEnumerable<ResourceData> resourceDatas)
//        {
//            HashSet<string> resourceGroupNames = new HashSet<string>();
//            foreach (ResourceData resourceData in resourceDatas)
//            {
//                foreach (string resourceGroup in resourceData.GetResourceGroups())
//                {
//                    resourceGroupNames.Add(resourceGroup);
//                }
//            }

//            return resourceGroupNames.OrderBy(x => x).ToArray();
//        }

//        private int[] GetResourceIndexesFromResourceGroup(IEnumerable<ResourceData> resourceDatas, string resourceGroupName)
//        {
//            int index = 0;
//            List<int> resourceIndexes = new List<int>();
//            foreach (ResourceData resourceData in resourceDatas)
//            {
//                foreach (string resourceGroup in resourceData.GetResourceGroups())
//                {
//                    if (resourceGroup == resourceGroupName)
//                    {
//                        resourceIndexes.Add(index);
//                        break;
//                    }
//                }

//                index++;
//            }

//            resourceIndexes.Sort();
//            return resourceIndexes.ToArray();
//        }

//        private void CreateFileSystems(IEnumerable<ResourceData> resourceDatas, string outputPath, Dictionary<string, IFileSystem> outputFileSystem)
//        {
//            outputFileSystem.Clear();
//            string[] fileSystemNames = GetFileSystemNames(resourceDatas);
//            if (fileSystemNames.Length > 0 && m_FileSystemManager == null)
//            {
//                m_FileSystemManager = GameFrameworkEntry.GetModule<IFileSystemManager>();
//                m_FileSystemManager.SetFileSystemHelper(new FileSystemHelper());
//            }

//            foreach (string fileSystemName in fileSystemNames)
//            {
//                int fileCount = GetResourceIndexesFromFileSystem(resourceDatas, fileSystemName).Length;
//                string fullPath = Utility.Path.GetRegularPath(Path.Combine(outputPath, Utility.Text.Format("{0}.{1}", fileSystemName, DefaultExtension)));
//                string directory = Path.GetDirectoryName(fullPath);
//                if (!Directory.Exists(directory))
//                {
//                    Directory.CreateDirectory(directory);
//                }

//                IFileSystem fileSystem = m_FileSystemManager.CreateFileSystem(fullPath, FileSystemAccess.Write, fileCount, fileCount);
//                outputFileSystem.Add(fileSystemName, fileSystem);
//            }
//        }

//        private bool ProcessOutput(Platform platform, string outputPackagePath, string outputFullPath, string outputPackedPath, bool additionalCompressionSelected, string name, string variant, string fileSystem, ResourceData resourceData, byte[] bytes, int length, int hashCode, int compressedLength, int compressedHashCode)
//        {
//            string fullNameWithExtension = Utility.Text.Format("{0}.{1}", GetResourceFullName(name, variant), GetExtension(resourceData));

//            if (OutputPackageSelected)
//            {
//                if (string.IsNullOrEmpty(fileSystem))
//                {
//                    string packagePath = Utility.Path.GetRegularPath(Path.Combine(outputPackagePath, fullNameWithExtension));
//                    string packageDirectoryName = Path.GetDirectoryName(packagePath);
//                    if (!Directory.Exists(packageDirectoryName))
//                    {
//                        Directory.CreateDirectory(packageDirectoryName);
//                    }

//                    File.WriteAllBytes(packagePath, bytes);
//                }
//                else
//                {
//                    if (!m_OutputPackageFileSystems[fileSystem].WriteFile(fullNameWithExtension, bytes))
//                    {
//                        return false;
//                    }
//                }
//            }

//            if (OutputPackedSelected && resourceData.Packed)
//            {
//                if (string.IsNullOrEmpty(fileSystem))
//                {
//                    string packedPath = Utility.Path.GetRegularPath(Path.Combine(outputPackedPath, fullNameWithExtension));
//                    string packedDirectoryName = Path.GetDirectoryName(packedPath);
//                    if (!Directory.Exists(packedDirectoryName))
//                    {
//                        Directory.CreateDirectory(packedDirectoryName);
//                    }

//                    File.WriteAllBytes(packedPath, bytes);
//                }
//                else
//                {
//                    if (!m_OutputPackedFileSystems[fileSystem].WriteFile(fullNameWithExtension, bytes))
//                    {
//                        return false;
//                    }
//                }
//            }

//            if (OutputFullSelected)
//            {
//                string fullNameWithCrc32AndExtension = variant != null ? Utility.Text.Format("{0}.{1}.{2:x8}.{3}", name, variant, hashCode, DefaultExtension) : Utility.Text.Format("{0}.{1:x8}.{2}", name, hashCode, DefaultExtension);
//                string fullPath = Utility.Path.GetRegularPath(Path.Combine(outputFullPath, fullNameWithCrc32AndExtension));
//                string fullDirectoryName = Path.GetDirectoryName(fullPath);
//                if (!Directory.Exists(fullDirectoryName))
//                {
//                    Directory.CreateDirectory(fullDirectoryName);
//                }

//                if (additionalCompressionSelected)
//                {
//                    byte[] compressedBytes = Utility.Compression.Compress(bytes);
//                    compressedLength = compressedBytes.Length;
//                    compressedHashCode = Utility.Verifier.GetCrc32(compressedBytes);
//                    File.WriteAllBytes(fullPath, compressedBytes);
//                }
//                else
//                {
//                    File.WriteAllBytes(fullPath, bytes);
//                }
//            }

//            resourceData.AddCode(platform, length, hashCode, compressedLength, compressedHashCode);
//            return true;
//        }

//        private BuildAssetBundleOptions GetBuildAssetBundleOptions()
//        {
//            BuildAssetBundleOptions buildOptions = BuildAssetBundleOptions.DeterministicAssetBundle;

//            if (ForceRebuildAssetBundleSelected)
//            {
//                buildOptions |= BuildAssetBundleOptions.ForceRebuildAssetBundle;
//            }

//            if (AssetBundleCompression == AssetBundleCompressionType.Uncompressed)
//            {
//                buildOptions |= BuildAssetBundleOptions.UncompressedAssetBundle;
//            }
//            else if (AssetBundleCompression == AssetBundleCompressionType.LZ4)
//            {
//                buildOptions |= BuildAssetBundleOptions.ChunkBasedCompression;
//            }

//            return buildOptions;
//        }

//        private bool PrepareBuildData(out AssetBundleBuild[] assetBundleBuildDatas, out ResourceData[] assetBundleResourceDatas, out ResourceData[] binaryResourceDatas)
//        {
//            assetBundleBuildDatas = null;
//            assetBundleResourceDatas = null;
//            binaryResourceDatas = null;
//            m_ResourceDatas.Clear();

//            Resource[] resources = m_ResourceCollection.GetResources();
//            foreach (Resource resource in resources)
//            {
//                m_ResourceDatas.Add(resource.FullName, new ResourceData(resource.Name, resource.Variant, resource.FileSystem, resource.LoadType, resource.Packed, resource.GetResourceGroups()));
//            }

//            Asset[] assets = m_ResourceCollection.GetAssets();
//            foreach (Asset asset in assets)
//            {
//                string assetName = asset.Name;
//                if (string.IsNullOrEmpty(assetName))
//                {
//                    m_BuildReport.LogError("Can not find asset by guid '{0}'.", asset.Guid);
//                    return false;
//                }

//                string assetFileFullName = Application.dataPath.Substring(0, Application.dataPath.Length - AssetsStringLength) + assetName;
//                if (!File.Exists(assetFileFullName))
//                {
//                    m_BuildReport.LogError("Can not find asset '{0}'.", assetFileFullName);
//                    return false;
//                }

//                byte[] assetBytes = File.ReadAllBytes(assetFileFullName);
//                int assetHashCode = Utility.Verifier.GetCrc32(assetBytes);

//                List<string> dependencyAssetNames = new List<string>();
//                DependencyData dependencyData = m_ResourceAnalyzerController.GetDependencyData(assetName);
//                Asset[] dependencyAssets = dependencyData.GetDependencyAssets();
//                foreach (Asset dependencyAsset in dependencyAssets)
//                {
//                    dependencyAssetNames.Add(dependencyAsset.Name);
//                }

//                dependencyAssetNames.Sort();

//                m_ResourceDatas[asset.Resource.FullName].AddAssetData(asset.Guid, assetName, assetBytes.Length, assetHashCode, dependencyAssetNames.ToArray());
//            }

//            List<AssetBundleBuild> assetBundleBuildDataList = new List<AssetBundleBuild>();
//            List<ResourceData> assetBundleResourceDataList = new List<ResourceData>();
//            List<ResourceData> binaryResourceDataList = new List<ResourceData>();
//            foreach (ResourceData resourceData in m_ResourceDatas.Values)
//            {
//                if (resourceData.AssetCount <= 0)
//                {
//                    m_BuildReport.LogError("Resource '{0}' has no asset.", GetResourceFullName(resourceData.Name, resourceData.Variant));
//                    return false;
//                }

//                if (resourceData.IsLoadFromBinary)
//                {
//                    binaryResourceDataList.Add(resourceData);
//                }
//                else
//                {
//                    assetBundleResourceDataList.Add(resourceData);

//                    AssetBundleBuild build = new AssetBundleBuild();
//                    build.assetBundleName = resourceData.Name;
//                    build.assetBundleVariant = resourceData.Variant;
//                    build.assetNames = resourceData.GetAssetNames();
//                    assetBundleBuildDataList.Add(build);
//                }
//            }

//            assetBundleBuildDatas = assetBundleBuildDataList.ToArray();
//            assetBundleResourceDatas = assetBundleResourceDataList.ToArray();
//            binaryResourceDatas = binaryResourceDataList.ToArray();
//            return true;
//        }

//        private static string GetResourceFullName(string name, string variant)
//        {
//            return !string.IsNullOrEmpty(variant) ? Utility.Text.Format("{0}.{1}", name, variant) : name;
//        }

//        private static BuildTarget GetBuildTarget(Platform platform)
//        {
//            switch (platform)
//            {
//                case Platform.Windows:
//                    return BuildTarget.StandaloneWindows;

//                case Platform.Windows64:
//                    return BuildTarget.StandaloneWindows64;

//                case Platform.MacOS:
//#if UNITY_2017_3_OR_NEWER
//                    return BuildTarget.StandaloneOSX;
//#else
//                    return BuildTarget.StandaloneOSXUniversal;
//#endif
//                case Platform.Linux:
//                    return BuildTarget.StandaloneLinux64;

//                case Platform.IOS:
//                    return BuildTarget.iOS;

//                case Platform.Android:
//                    return BuildTarget.Android;

//                case Platform.WindowsStore:
//                    return BuildTarget.WSAPlayer;

//                case Platform.WebGL:
//                    return BuildTarget.WebGL;

//                default:
//                    throw new GameFrameworkException("Platform is invalid.");
//            }
//        }

//        private static string GetExtension(ResourceData data)
//        {
//            if (data.IsLoadFromBinary)
//            {
//                string assetName = data.GetAssetNames()[0];
//                int position = assetName.LastIndexOf('.');
//                if (position >= 0)
//                {
//                    return assetName.Substring(position + 1);
//                }
//            }

//            return DefaultExtension;
//        }
//    }
//}
